package com.probiz.estoresa.system.web.action;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.validation.BindException;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.servlet.ModelAndView;

import com.probiz.estore.Constants;
import com.probiz.estore.common.helper.ConfigUtil;
import com.probiz.estore.common.model.system.AppAdmin;
import com.probiz.estore.common.model.system.AppRole;
import com.probiz.estore.common.model.system.AppUser;
import com.probiz.estore.core.controller.GenericStoreAdminController;
import com.probiz.estore.core.exception.ApplicationException;
import com.probiz.estore.core.search.SearchCriteria;
import com.probiz.estore.core.util.StringUtil;
import com.probiz.estore.system.model.AppAdminSearchCriteria;
import com.probiz.estore.system.service.AppAdminManager;
import com.probiz.estore.system.service.AppRoleManager;
import com.probiz.estore.system.service.MsgSendManager;
import com.probiz.estore.system.util.MsgTemplateConstants;
import com.probiz.estore.webapp.util.RequestContext;
import com.probiz.estore.webapp.util.RequestUtil;


public class AppAdminController extends GenericStoreAdminController<AppAdmin> {
    private AppAdminManager appAdminManager;
    
    private AppRoleManager appRoleManager;
    
    private MsgSendManager msgSendManager;

	public void setAppAdminManager(AppAdminManager appAdminManager) {
        this.appAdminManager = appAdminManager;
    }
	
	public void setAppRoleManager(AppRoleManager appRoleManager) {
		this.appRoleManager = appRoleManager;
	}
	
	
	public void setMsgSendManager(MsgSendManager msgSendManager) {
		this.msgSendManager = msgSendManager;
	}

	@Override
	protected String getEntityName(AppAdmin entity) {
		return entity.getUsername();
	}

	
	@Override
	protected void preSave(HttpServletRequest request, AppAdmin entity, BindException errors) {

	}
	
	@Override
	protected void onShowForm(HttpServletRequest request, ModelAndView mv) {
		super.onShowForm(request, mv);
		mv.addObject("allRoles",appRoleManager.findAppRoles(new Short("0")));
	}

	@Override
	protected void initController() throws Exception {
		this.mgr = appAdminManager;
		this.getServletContext().setAttribute("DEFAULT_ADMIN_USER_NAME", Constants.DEFAULT_ADMIN_USER_NAME);
	}

	
    
	public ModelAndView defaultAction(HttpServletRequest request,  HttpServletResponse response) {
		ModelAndView mv = new ModelAndView("system/security/appAdminList");
		return mv;
    }
	
	public ModelAndView search(HttpServletRequest request,HttpServletResponse response) {
		ModelAndView mv = new ModelAndView("system/security/include/appAdminListBody");
		SearchCriteria searchCriteria = createSearchCriteria(request);
		AppAdminSearchCriteria appAdminSearchCriteria = new AppAdminSearchCriteria();
		try {
			// 绑定参数
			bind(request, appAdminSearchCriteria);
			List<AppAdmin> appAdminList = appAdminManager.searchByCriteria(appAdminSearchCriteria,	searchCriteria);
			mv.addObject("appAdminList", appAdminList);
			mv.addObject("appAdminSearchCriteria", appAdminSearchCriteria);
			
			List<AppRole> allRoles = appRoleManager.getSystemRoles();
			mv.addObject("allRoles", allRoles);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return mv;
	}
	
	
    public ModelAndView multiDelete(HttpServletRequest request, HttpServletResponse response) {
    	Map<String, Object> data = new HashMap<String, Object>();
        String[] ids = request.getParameterValues("multiIds");
        if (ids != null) {
            for (int i = 0; i < ids.length; i++) {
                AppAdmin appAdmin = mgr.getById(Integer.valueOf(ids[i]));
                if(!appAdmin.getUsername().equalsIgnoreCase(Constants.DEFAULT_ADMIN_USER_NAME)){
					appAdminManager.deleteFully(appAdmin);
                }
            }
            String message = getMessage("common.deleted.multi", new Object[] {getEntityTypeMessage(), ids.length });
            data.put("msg",message); 
        }
								
		return getModelAndAjaxJsonView(data);
    }    
    
    
    public ModelAndView multiSave(HttpServletRequest request, HttpServletResponse response) {
    	Map<String, Object> data = new HashMap<String, Object>();
        String[] ids = request.getParameterValues("appuserId");
        String[] statuses = request.getParameterValues("ck_status");
        int iLen = statuses.length;
        for (int i = 0; i < iLen; i++) {
            AppAdmin appAdmin = mgr.getById(new Integer(ids[i]));
            appAdmin.setStatus(new Short(statuses[i]));
            mgr.save(appAdmin);
        }

        String message = getMessage("common.updated.multi");
        data.put("msg",message);    		
	    return getModelAndAjaxJsonView(data);
    }    
    
    public ModelAndView save(HttpServletRequest request, HttpServletResponse response) throws Exception {
    	Map<String, Object> data = new HashMap<String, Object>();
    	// 取得Form对应的Model
    	AppAdmin appAdmin = formBackingObject(request);

		BindException errors = null;
		try {
			ServletRequestDataBinder binder = bindAndValidate(request, appAdmin);
			errors = new BindException(binder.getBindingResult());
			if (!errors.hasErrors()) {// 里面如果出错应该抛出异常
				preSave(request, appAdmin, errors);
				if(appAdmin.getAppuserId()==null){//when add a new user
		 	    	boolean isUserExist=appAdminManager.getIsUserExist(appAdmin.getUsername());
		 	    	if(isUserExist){
		 	    		data.put("error", this.getMessage("appUser.username.isExist"));
		 	    		return  this.getModelAndAjaxJsonView(data);
		 	    	}else if(appAdminManager.getIsEmailExist(appAdmin.getEmail())){
		 	    	   data.put("error", this.getMessage("appUser.email.isExist"));
		 	    	   return  this.getModelAndAjaxJsonView(data);
		 	    	}
		        	//set user type for admin user
		        	appAdmin.setUserType(AppUser.USER_TYPE_ADMIN);
		        	//set unlock staus
		        	appAdmin.setIsLocked(AppUser.CONST_UNLOCKED);
		        	//set user status to unactive 
		        	appAdmin.setStatus(Constants.STATUS_ACTIVE);
		        	appAdmin.setDeleted(AppAdmin.CONST_UNDELETED);
		        	appAdmin.setPassword(StringUtil.encodePassword(appAdmin.getPassword(), ConfigUtil.getInstance().getPasswordEncryptionAlgorithm()));
		 	    	
		 		}else{//update
			        boolean isEmailExist=false;
			        //check existence of the user's email
			        isEmailExist=appAdminManager.getIsEmailUseByOthers(appAdmin.getEmail(),appAdmin.getAppuserId());
			        if(isEmailExist){
			            data.put("error", this.getMessage("appUser.email.isExist"));
			            return this.getModelAndAjaxJsonView(data);
				    }
			    }
				
				//set the roles for current appadmin
		        appAdmin.getUserRoles().clear();
		        String[] appRoleIds=request.getParameterValues("appRoleIds");
		        if(appRoleIds!=null){
		            for(int i=0;i<appRoleIds.length;i++){
		            	AppRole role=appRoleManager.getById(new Integer(appRoleIds[i]));
		            	appAdmin.getUserRoles().add(role);
		            }
		        }
		        //if the current user is admin user,then set the admin role.
		        if(appAdmin.getIsSuperAdmin()){
		        	AppRole adminRole=appRoleManager.getAdminRole();
		        	if(!appAdmin.getUserRoles().contains(adminRole)){
		        		appAdmin.getUserRoles().add(adminRole);
		        	}
		        }
		        //add or update appadmin object.
		        appAdminManager.save(appAdmin);
		        data.put("appAdminId", appAdmin.getAppAdminId());
			}
		} catch (ApplicationException e) {
			handleApplicationException(errors, e);
		}
        
    	return this.getModelAndAjaxJsonView(data);
    }
    
    @Override
    protected AppAdmin formBackingObject(HttpServletRequest request){
		String appAdminId = request.getParameter("appAdminId");
		AppAdmin appAdmin = null;
		List allRoles=appRoleManager.findAppRoles(new Short("0"));
		if (StringUtils.isNotEmpty(appAdminId)) {
		  try {
		
		    Integer   pkey =  (new Integer(appAdminId));
		    appAdmin = appAdminManager.getById(pkey);
		
			// Error retrieving value - so assume it is new
		   } catch (Exception ex) {
		   		 ex.printStackTrace();
		   		 appAdmin = new AppAdmin();
		   }
		} else {
		    appAdmin = new AppAdmin();
		}
		
		// for unit tests - so we can grab an object to save
		request.setAttribute("allRoles", allRoles);
		return appAdmin;
    }
    
    
	/**
	 * 打开重设密码页面
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */ 
    public ModelAndView resetPassword(HttpServletRequest request,HttpServletResponse response) throws Exception {
      ModelAndView mv = new ModelAndView("system/userPasswordForm");
      AppAdmin appuser = appAdminManager.getById(RequestUtil.getInteger(request,"appuserId"));
      mv.addObject("appuser", appuser);
      return mv;
    }
    /**
     * 保存密码
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    public ModelAndView saveResetPassword(HttpServletRequest request,	HttpServletResponse response) throws Exception{
    	Map<String, Object> data = new HashMap<String, Object>();
    	try {
			Integer appuserId = RequestUtil.getInteger(request, "appuserId");
			String password = RequestUtil.getParameterNullSafe(request, "password");
			appAdminManager.saveModifyPassword(appuserId,password);
			Map msgVariables = new HashMap();
			AppUser appUser = appAdminManager.getById(appuserId);
			msgVariables.put("userName", appUser.getUsername());
			msgVariables.put("newPassword", password);
			msgSendManager.sendMsg(MsgTemplateConstants.MESSAGE_CHANGE_PASSWORD, msgVariables, new String[]{appUser.getEmail()}, new String[]{ appUser.getAppuserId().toString()}, new String[]{appUser.getMobilephone()});
		} catch (RuntimeException e) {
			data.put("error", e.getMessage());
		}
		return this.getModelAndAjaxJsonView(data);
    }
    

	/**
	 * 删除一条记录。并在应用级出错的时候显示出错信息。
	 * 
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	public ModelAndView delete(HttpServletRequest request,	HttpServletResponse response) throws Exception {
		Map<String, Object> data = new HashMap<String, Object>();
		// 取得Form对应的Model。因为要先保存其名称，否则可能会连I18N数据也已经删除了；另外可以用于出错的时候恢复显示Form页面
		AppAdmin entity = formBackingObject(request);
		
		// 删除并设置信息
		String entityId = request.getParameter(entityIdName);
		if (!StringUtils.isEmpty(entityId)) {
			// 先构造提示信息，否则信息对应的记录可能也会被删除。
			String entityName = getEntityName(entity);
			try {
				appAdminManager.deleteFully(entity);
			} catch (DataIntegrityViolationException e) {
				e.printStackTrace();
				saveErrorMessage(request, this.getMessage("common.message.delete.constraintViolation"));
				
				// 为了出错的时候可以恢复表单显示，构造errors。无须作表单绑定和验证
				ServletRequestDataBinder binder = this.getDefaultBinder(request,entity);
				BindException errors = new BindException(binder.getBindingResult());
				
				return showForm(request, errors);
			}
			String message = getMessage("common.deleted", new Object[] {
					getEntityTypeMessage(), entityName });
			data.put("msg",message);
		} else {
			data.put("msg", getMessage("errors.invalid.delete.id",	new Object[] { entityId }));
		}
		return getModelAndAjaxJsonView(data);
	}
  	  	
}
